
#include "GLshader.h"

unsigned char *readShaderFile( const char *fileName )
{
	FILE *file = fopen( fileName, "r" );
	int iFileSize  = 0;
	
	if( file == NULL )
	{
		MessageBox( NULL, "Cannot open shader file!", "ERROR",
			MB_OK | MB_ICONEXCLAMATION );
		return 0;
	}
	
	fseek(file,0,SEEK_END);
	iFileSize = ftell(file);
	fseek(file,0,SEEK_SET);
	
	unsigned char *buffer = new unsigned char[iFileSize];
	
	int bytes = fread( buffer, 1, iFileSize, file );
	
	buffer[bytes] = 0;
	
	fclose( file );
	
	return buffer;
}

void writeLog( const char *sLog )
{
	FILE *file = fopen( "error.log", "w+" );
	int bytes = fwrite( sLog, 1, strlen(sLog)+1, file );
	
	fclose( file );	
}

bool ShaderPack::CreateAndCompileShaders(char* sVsFile,char* sPsFile)
{
	const char *vertexShaderStrings[1];
	const char *fragmentShaderStrings[1];
	
	char str[1024] = {0};
	
	int bVertCompiled = false;
	int bFragCompiled = false;
	int bLinked		  = false;
	
	GLhandleARB shader = NULL;
	
	GLhandleARB vs = 0;
	
	if( sVsFile )
	{
		vs =glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
		unsigned char *vertexShaderAssembly = readShaderFile( sVsFile);
		vertexShaderStrings[0] = (char*)vertexShaderAssembly;
		GLenum e = glGetError();
		
		glShaderSourceARB( vs, 1, vertexShaderStrings, NULL );
		glCompileShaderARB( vs);
	
		e = glGetError();
		delete vertexShaderAssembly;
		
		glGetObjectParameterivARB( vs, GL_OBJECT_COMPILE_STATUS_ARB, 
			&bVertCompiled );
	
		if( bVertCompiled == false )
		{
			glGetInfoLogARB(vs, sizeof(str), NULL, str);
			WriteLogToFile(str);
			return false;
		}
	}

	GLhandleARB ps = 0;
	
	if( sPsFile) 
	{	
		ps = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
		
		unsigned char *fragmentShaderAssembly = readShaderFile( sPsFile );
		fragmentShaderStrings[0] = (char*)fragmentShaderAssembly;
		glShaderSourceARB( ps, 1, fragmentShaderStrings, NULL );
		glCompileShaderARB( ps );
		delete fragmentShaderAssembly;
		
		glGetObjectParameterivARB( ps, GL_OBJECT_COMPILE_STATUS_ARB, 
			&bFragCompiled );
		if( bFragCompiled == false )
		{
			glGetInfoLogARB( ps, sizeof(str), NULL, str );
			WriteLogToFile(str);
			return false;
		}
	}	
	
	shader = glCreateProgramObjectARB();
	
	glAttachObjectARB( shader, vs );
	glAttachObjectARB( shader, ps );
	
	glLinkProgramARB( shader );	
	glLinkProgramARB( shader );

	glGetObjectParameterivARB( shader, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
	
	if( bLinked == false )
	{
		glGetInfoLogARB( shader, sizeof(str), NULL, str );
		WriteLogToFile(str);
		return false;
	}
	

	this->hPs		= ps;
	this->hVs		= vs;
	this->hShader	= shader;
	
	return true;
}